#include <vector>
#include <iostream>
#include <algorithm>
#include <array>
#include <list>
#include <unordered_map>
void printV(int val)
{
    using namespace std;
    cout << val << endl;
}

void testVectorIterator();
void testVectorErase();
void testArray();
void testListSplice();
void testListMerge();
void testVectorInit();
void testUnoderedMap();

int main(int argc, char const *argv[])
{
    // testArray();
    testVectorErase();
    // testListSplice();
    // testListMerge();
    // testVectorInit();
    // testUnoderedMap();
    return 0;
}

void testArray()
{
    // array是个数不变的数组，从C++ 11中才被引入，比如wcdb中的例子
    //  static const std::array<std::string, 5> &subfixs()
    /*
        const std::array<std::string, 5> &Database::subfixs()
        {
            static const std::array<std::string, 5> s_subfixs = {
                "", //db file
                "-wal", "-journal", "-shm", Handle::backupSuffix,
            };
            return s_subfixs;
        }
    */

    std::array<int, 3> myarray = {4, 12, 8};
    for (auto ele : myarray)
    {
        std::cout << ele << std::endl;
    }
}

void testVectorErase()
{
    std::vector<int> myvector;
    for (size_t i = 0; i < 10; i++)
    {
        myvector.push_back(i);
    }

    // 开始的一个会被删除
    myvector.erase(myvector.begin());
    // 包含开始但是不包含结束，两个会被删除
    // 可以简单理解为算上开始, 一共删除几个
    myvector.erase(myvector.begin(), myvector.begin() + 2);
    for (auto item : myvector)
    {
        std::cout << item << std::endl;
    }
}

// 初始化vector的几种方法：
/*
1. vector<int> months(12); // 初始化12个元素
2. vector<int> months(12, 0); // 初始化12个元素，每个元素的初始化值都是0
3. vector<int> months; 之后调用moths.push_back()方法
*/
void testVectorInit() {
    // 初始化12个元素
    std::vector <int> months(12);
    int i = 1;
    for(auto &m: months) {
        m = i;
        i = i + 1;
    }

    for(auto m: months) {
        std::cout << "vector ele: " << m << std::endl;
    }
}

void testUnoderedMap() {
    std::unordered_map<std::string, std::string> unorderMap = {
        {"red","#FF0000"}, // 和OC不一样的是这里是逗号
        {"green","#00FF00"},
        {"blue","#0000FF"}
    };
    // 添加元素
    unorderMap.insert({"cyan","#98833f"});
    auto print_map = [](const auto &first, const auto &second) {
        std::cout << "first: " << first << " second: " << second << "\n";
    };
    unorderMap["black"] = "#000000";
    std::cout << "使用pair的形式来进行遍历\n";
    for (const std::pair<const std::string, std::string> &pair: unorderMap) {
        print_map(pair.first, pair.second);
    }
    std::cout << "直接使用auto进行遍历\n";
    // 直接使用auto进行遍历
    for(const auto &p: unorderMap) {
        print_map(p.first, p.second);
    }
    // 通过key找到对应的value
    auto ite = unorderMap.find("red");
    std::cout << "red: " << (*ite).second << "\n";
    // 如果没有找到，那么对应的iterator就是end
    std::unordered_map<std::string, std::string>::iterator ite1 = unorderMap.find("yellow");
    // 使用auto更加方便
    const auto ite2 = unorderMap.find("blue");
    if(ite1 == unorderMap.end()) {
        std::cout << "未找到 yellow的value\n";
    }

}

// vector是可以伸缩的数组
void testVectorIterator()
{
    using namespace std;
    vector<int> v;
    v.push_back(100);
    v.push_back(200);
    v.push_back(300);
    v.push_back(400);

    // 在某个位置插入数据
    v.insert(v.begin(), 90);
    cout << "size: " << v.size() << endl;
    vector<int>::iterator itebegin = v.begin();
    vector<int>::iterator iteEnd = v.end();
    cout << "遍历数组的方式:while:" << endl;
    while (itebegin != iteEnd)
    {
        cout << *(itebegin) << endl;
        itebegin++;
    }

    cout << "遍历数组的方式:for_each:" << endl;
    for_each(v.begin(), v.end(), printV);
    for (vector<int>::iterator it = v.begin(); it < v.end(); it++)
    {
        cout << "第: " << it - v.begin() << "个数据是:" << *it << endl;
    }

    cout << "使用C++11的for形式进行遍历" << endl;
    for (auto &num : v)
    {
        cout << num << endl;
    }

    cout << "use c++ 11 closure's style to iterator the vector" << endl;
    for_each(v.begin(), v.end(), [](int itm)
                  { cout << itm << endl; });
}

// list比vector更加高级，它可以在任何位置插入和删除【不像vector只支持push_back】，同时还支持两个list的splice，在特定的位置插入
void testListSplice()
{
    std::list<int> aList;
    for (size_t i = 0; i < 3; i++)
    {
        aList.push_front(i);
    }
    std::list<int> bList = {10, 20, 30};
    std::list<int>::iterator it = bList.begin();
    ++it;
    // 经过splice之后被splice的aList数据没有了，变成了空数组
    bList.splice(it, aList);
    std::cout << "aList最后的值:" << std::endl;
    for (auto aItem : aList)
    {
        std::cout << aItem << std::endl;
    }
    std::cout << "最后it的值" << *it << std::endl;
}

// compare only integral part:
bool mycomparison(double first, double second)
{
    return (int(first) < int(second));
}

// merge是混着插入的，插入的时候还会排序，所以要保证顺序的话，需要实现compare方法
void testListMerge()
{
    using namespace std;
    std::list<double> first, second;

    first.push_back(3.1);
    first.push_back(2.2);
    first.push_back(2.9);

    second.push_back(3.7);
    second.push_back(7.1);
    second.push_back(1.4);

    first.sort();
    second.sort();
    cout << "first: " << endl;
    for (auto ele : first)
    {
        cout << ele << endl;
    }
    cout << "scond: " << endl;
    for (auto ele : second)
    {
        cout << ele << endl;
    }
    first.merge(second);

    cout << "merged first: " << endl;
    for (auto ele : first)
    {
        cout << ele << endl;
    }

    cout << "merged scond: " << endl;
    for (auto ele : second)
    {
        cout << ele;
    }
    cout << endl;
    second.push_back(2.1);
    cout << "push_back scond: " << endl;
    for (auto ele : second)
    {
        cout << ele;
    }
    cout << endl;

    first.merge(second, mycomparison);

    std::cout << "first contains:";
    for (std::list<double>::iterator it = first.begin(); it != first.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';
    /*
    first:
    2.2
    2.9
    3.1
    scond:
    1.4
    3.7
    7.1
    merged first:
    1.4
    2.2
    2.9
    3.1
    3.7
    7.1
    merged scond:

    push_back scond:
    2.1
    first contains: 1.4 2.2 2.9 2.1 3.1 3.7 7.1
    */
}
